/**
 * 
 */
package view.impl.menu.items;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.UnicodeFont;
import org.newdawn.slick.geom.Polygon;
import org.newdawn.slick.geom.RoundedRectangle;
import org.newdawn.slick.geom.Transform;


/**
 * A class that defines and draws a checkbox. Implements the interface IMenuItem
 * which makes it usable together with the rest of the menu system.
 * 
 * @author Julian
 *
 */
public class MenuCheckBox implements IMenuItem {
	
	private final static int BOXWIDTH = 30;
	private final static int BOXHEIGHT = 30;
	
	private String textBefore;
	private String textAfter;
	private UnicodeFont uFont;
	private Color fontColor;
	
	private int posX;
	private int posY;
	
	private boolean checked = false;
	
	private IMenuArrow arrows;
	
	/**
	 * Simplest constructor used to make the most basic checkbox.
	 * 
	 * @param textBefore Text to be displayed before the box.
	 * @param textAfter Text to be displayed after the box.
	 * @param uFont UnicodeFont to use for the text.
	 */
	public MenuCheckBox(String textBefore, String textAfter, UnicodeFont uFont) {
		this(textBefore, textAfter, uFont, 0, 0);
	}
	
	/**
	 * Simple constructor used to make a basic checkbox.
	 * 
	 * @param textBefore Text to be displayed before the box.
	 * @param textAfter Text to be displayed after the box.
	 * @param uFont UnicodeFont to use for the text.
	 * @param posX The horizontal position.
	 * @param posY The vertical position.
	 */
	public MenuCheckBox(String textBefore, String textAfter, UnicodeFont uFont, int posX, int posY) {
		this(new MenuArrow(posX, 
						   posY, 
						   (int) (uFont.getWidth(textBefore) + uFont.getWidth(textAfter) + 
								  (BOXWIDTH + 10) * 1), // scaleX 
						   uFont.getHeight(textBefore)), 
				 textBefore,
				 textAfter,
				 uFont, 
				 posX, 
				 posY, 
				 new Color(255, 185, 25));
	}
	
	/**
	 * 
	 * Constructor to make a very customized checkbox.
	 * 
	 * @param arrows The specified arrows to use.
	 * @param textBefore Text to be displayed before the box.
	 * @param textAfter Text to be displayed after the box.
	 * @param uFont UnicodeFont to use for the text rendering.
	 * @param posX The horizontal position.
	 * @param posY The vertical position.
	 * @param fontColor The color to render the text in.
	 */
	public MenuCheckBox(IMenuArrow arrows, String textBefore, String textAfter, UnicodeFont uFont, int posX, int posY, Color fontColor) {
		this.arrows = arrows;
		this.textBefore = textBefore;
		this.textAfter = textAfter;
		this.uFont = uFont;
		this.posX = posX;
		this.posY = posY;
		this.fontColor = fontColor;
	}
	
	/**
	 * Method to set whether the checkbox should be checked or not.
	 * 
	 * @param checked Should the box be checked?
	 */
	public void setChecked(boolean checked) {
		this.checked = checked;
	}
	
	/**
	 * Method to see if the checkbox is checked.
	 * 
	 * @return Whether the box is checked or not.
	 */
	public boolean isChecked() {
		return checked;
	}
	
	/**
	 * Update the font used in text rendering. Necessary when the resolution
	 * has been changed.
	 * 
	 * @param uFont The UnicodeFont to use.
	 */
	public void updateFont(UnicodeFont uFont) {
		this.uFont = uFont;
	}
	
	/* (non-Javadoc)
	 * @see client.view.IMenuItem#draw(boolean)
	 */
	@Override
	public void draw(boolean selected, Graphics g, int windowWidth, int windowHeight) {
		
		// Init values.
		float scaleX = (float)windowWidth / 800f;
		float scaleY = (float)windowHeight / 600f;
		float averageScale = (scaleX + scaleY) / 2;
		
		int textBeforeWidth = uFont.getWidth(textBefore);
		
		int centeredPosY = posY + uFont.getHeight(textBefore) / 2;
		
		// Draw stuff.
		
		// Draw textBefore.
		uFont.drawString(posX, posY, textBefore, fontColor);
		
		// Draw checkbox.
		RoundedRectangle box = new RoundedRectangle(posX + textBeforeWidth + 5 * scaleX, 
										 			(float) (centeredPosY - BOXHEIGHT * scaleY * 0.5), 
										 			BOXWIDTH, 
										 			BOXHEIGHT, 
										 			3 * averageScale);
		g.setAntiAlias(true);
		g.setColor(Color.white);
		g.fill(box);
		g.setLineWidth(3 * averageScale);
		g.setColor(Color.cyan);
		g.draw(box);
		g.setLineWidth(1);
		
		if(checked) {
			// Draw "checker".
			float[] points = { 1, -1, 3, -8, 5, -12, 8, -16, 19, -16, 14, -9, 
							   10, -1, 7, 6, 3, 17, -3, 17, -4, 14, -7, 10, -12, 
							   6, -18, 2, -13, -7, -8, -3, -5, 0, -2, 4, 0, 9 };
			
			Polygon checker = new Polygon(points);
			checker.transform(Transform.createScaleTransform(scaleX, scaleY));
			
			checker.setLocation(posX + textBeforeWidth + 2 * scaleX, posY);
			
			g.setAntiAlias(true);
			g.setColor(Color.black);
			g.fill(checker);
		}
		
		// Draw textAfter.
		uFont.drawString(posX + textBeforeWidth + box.getWidth() + 10 * scaleX, centeredPosY, textAfter, fontColor);
		
		if(selected) {
			// Draw arrows.
			arrows.draw(g, windowWidth, windowHeight);
		}
	}

	/* (non-Javadoc)
	 * @see client.view.IMenuItem#getHeight()
	 */
	@Override
	public int getHeight() {
		float scaleY = 1;
		if(BOXHEIGHT * scaleY > uFont.getLineHeight()) {
			return (int) (BOXHEIGHT * scaleY);
		}
		else {
			return uFont.getLineHeight();
		}
	}

	/* (non-Javadoc)
	 * @see client.view.IMenuItem#getPosX()
	 */
	@Override
	public int getPosX() {
		return posX;
	}

	/* (non-Javadoc)
	 * @see client.view.IMenuItem#getPosY()
	 */
	@Override
	public int getPosY() {
		return posY;
	}

	/* (non-Javadoc)
	 * @see client.view.IMenuItem#getWidth()
	 */
	@Override
	public int getWidth() {
		float scaleX = 1;
		return (int) (uFont.getWidth(textBefore) + 
					  (10 + BOXWIDTH) * scaleX + 
					  uFont.getWidth(textAfter));
	}

	/* (non-Javadoc)
	 * @see client.view.IMenuItem#move(int, int)
	 */
	@Override
	public void move(int deltaX, int deltaY) {
		setPos(posX + deltaX, posY + deltaY);
	}

	/* (non-Javadoc)
	 * @see client.view.IMenuItem#setPos(int, int)
	 */
	@Override
	public void setPos(int posX, int posY) {
		this.posX = posX;
		this.posY = posY;
		arrows.setPosition(posX, posY);
	}

}
